using Circus.CodeEditor;
using Circus.CodeEditor.TextSource;
using Circus.Syntax;
using Circus.Syntax.CodeCompletion;
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Circus.CodeEditor.CodeCompletion
{
	public class HtmlSyntaxPaint : SyntaxPaint, IDisposable
	{
		private ICodeCompletionProvider provider;
		private HtmlLexer internalLexer;
		public ICodeCompletionProvider Provider
		{
			get
			{
				return this.provider;
			}
			set
			{
				if (this.provider != value)
				{
					this.provider = value;
					this.OnProviderChanged();
				}
			}
		}
		private void AddLine(string str, StringItemInfo[] data, int shift)
		{
			if (str.Length == data.Length && str.Length > shift)
			{
				StringItemInfo[] array = new StringItemInfo[data.Length - shift];
				Array.Copy(data, shift, array, 0, array.Length);
				this.AddLine(str.Substring(shift), array);
			}
		}
		protected virtual void OnProviderChanged()
		{
			if (this.provider != null && this.provider.UseHtmlFormatting)
			{
				if (this.Lexer == null)
				{
					this.Lexer = this.internalLexer;
				}
			}
			else
			{
				if (this.Lexer == this.internalLexer)
				{
					this.Lexer = null;
				}
			}
		}
		protected bool IsDelimiter(string s, int pos)
		{
			char c = s[pos];
			return c <= ' ' || EditConsts.DefaultDelimiters.IndexOf(c) >= 0;
		}
		protected void AddMultiLine(string s, int state, Point startPos, bool useLexer, bool isFullText)
		{
			s = s.Replace("\t", new string(' ', EditConsts.DefaultSpacesInTab));
			StringItemInfo[] data = null;
			if (useLexer && this.PrepareData(state, FontStyle.Regular, ref s, ref data))
			{
				this.AddMultiLine(s, data);
			}
			else
			{
				int num = startPos.Y;
				int num2 = -1;
				bool flag = false;
				string[] array = StringItem.Split(s);
				string[] array2;
				if (isFullText)
				{
					array2 = array;
					for (int i = 0; i < array2.Length; i++)
					{
						string text = array2[i];
						if (num == startPos.Y && startPos.X >= text.TrimEnd(new char[0]).Length)
						{
							num++;
							flag = true;
						}
						else
						{
							if (text.Trim() != string.Empty)
							{
								if (num2 == -1)
								{
									num2 = text.Length - text.TrimStart(new char[0]).Length;
								}
								else
								{
									num2 = Math.Min(num2, text.Length - text.TrimStart(new char[0]).Length);
								}
							}
							num++;
						}
					}
				}
				num = startPos.Y;
				array2 = StringItem.Split(s);
				for (int i = 0; i < array2.Length; i++)
				{
					string text = array2[i];
					if (flag && num == startPos.Y)
					{
						num++;
					}
					else
					{
						data = new StringItemInfo[text.Length];
						if (useLexer && this.Lexer != null)
						{
							state = this.Lexer.ParseText(state, num, text, ref data);
						}
						if (num2 != -1 && num2 < text.Length && num != startPos.Y)
						{
							this.AddLine(text, data, num2);
						}
						else
						{
							if (isFullText && num == startPos.Y)
							{
								this.AddLine(text, data, startPos.X);
							}
							else
							{
								this.AddLine(text, data);
							}
						}
						num++;
					}
				}
			}
		}
		protected void AddMultiLine(string s, StringItemInfo[] data)
		{
			int num = 0;
			int i = 0;
			int length = s.Length;
			while (i < length)
			{
				if (s[i] == '\r' || s[i] == '\n')
				{
					this.AddSubstring(s, data, num, i - num);
					if (s[i] == '\r' && i < length - 1 && s[i + 1] == '\n')
					{
						i++;
					}
					i++;
					num = i;
				}
				else
				{
					i++;
				}
			}
			this.AddSubstring(s, data, num, length - num);
		}
		protected void AddSubstring(string s, StringItemInfo[] data, int start, int len)
		{
			StringItemInfo[] array = new StringItemInfo[len];
			Array.Copy(data, start, array, 0, len);
			this.AddLine(s.Substring(start, len), array);
		}
		protected virtual void AddLine(string s, StringItemInfo[] data)
		{
		}
		public HtmlSyntaxPaint(Painter painter, Control control) : base(painter, control)
		{
			this.internalLexer = new HtmlLexer();
		}
		~HtmlSyntaxPaint()
		{
			this.Dispose(false);
		}
		public virtual bool PrepareData(int state, FontStyle style, ref string s, ref StringItemInfo[] colorData)
		{
			if (this.Lexer is HtmlLexer)
			{
				((HtmlLexer)this.Lexer).ParseHtmlText(state, style, ref s, ref colorData);
			}
			else
			{
				colorData = new StringItemInfo[s.Length];
			}
			return this.Lexer is HtmlLexer;
		}
		protected virtual void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (this.internalLexer != null)
				{
					this.internalLexer.Dispose();
					this.internalLexer = null;
				}
			}
		}
		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}
	}
}
